<template>
  <el-container class="process-design-wrap" v-loading="processLoading">

    <!-- 头部组件 -->
    <el-header class="page-header">
      <div class="process-header">
        <div class="process-header_title">{{ modelData.name }}</div>
        <div>
          <el-select
            style="width: 240px;margin-right: 10px"
            v-model="curVersion"
            placeholder="请选择版本"
            @change="handleCurVersionChange"
          >
            <el-option
              v-for="ver in versionList"
              :key="ver.id"
              :value="ver.id"
              :label="ver.versionText"
            >
            </el-option>
          </el-select>
          <el-dropdown split-button type="primary" @click="handleSave(true)" @command="handleCommandSave" >
            <i class="el-icon-upload"></i>
            <span>保存</span>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item :disabled="!processCanActivate" command="activate">保存并激活</el-dropdown-item>
              <el-dropdown-item :disabled="!processCanPublish" command="publish">保存并发布</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
          <el-button style="margin-left: 10px" @click="handleClose">关闭页面</el-button>
        </div>
      </div>
    </el-header>
    <div style="height:calc(100% - 60px)">
      <!--      状态机设计-->
      <g6-process :elements="elements" :processCanPublish="processCanPublish" ref="g6process" @save="handleSave" />
    </div>
  </el-container>
</template>

<script>
import G6Process from './__components__/graphBasic'
import { cloneDeep } from 'lodash'
import { getHmstatemodelHistory,getHmstatemodelInfo,putHmstatemodelDeploy,putHmstatemodelPublish,putHmstatemodelActivate } from '@/apis/paas/HmStateModelController.js'
import store from './__components__/store'
import { COMMON_CODE_28I_REG } from '@/utils/reg'
export default {
  name: 'StateDesign',
  components: { G6Process },
  layout: 'formlayout',
  data () {
    return {
      versionList: [],
      modelData: {
        id: undefined,
        key: '',
        name: '',
        category: '',
        description: ''
      },
      processLoading: false,
      curVersion: undefined,
      elements: []
    }
  },
  computed: {
    processCanActivate() {
      return this.modelData?.activated === 0
    },
    processCanPublish () {
      return this.modelData?.published !== 1
    },
    curVerssionData () {
      const { curVersion, versionList } = this
      if (!curVersion) {
        return undefined
      } else {
        return versionList.find(ver => ver.id === curVersion)
      }
    }
  },
  created () {
    const { id, key } = this.$route.query
    this._id = id ? Number(id) : undefined
    this._key = key
    this.curVersion = this._id
    this.loadVersionList(this._key)
  },
  mounted () {
    this.initProcess()
  },
  methods: {
    /**
     * 初始化
     */
    initProcess () {
      if (!this.curVersion) {
        return
      }
      getHmstatemodelInfo({
        id: this.curVersion,
        includeJson: true
      }).then(res => {
        this.modelData = {
          ...res,
          category: res.folderName
        }
        this.$refs.g6process.initData(res.json)
      })
    },

    loadVersionList (key = '') {
      getHmstatemodelHistory({
        key
      }).then(res => {
        this.versionList = res.map(item => {
          item.versionText = this.$options.filters['version'](item.version) + `${item.published ? '【已发布】' : ''}` + `${item.activated ? '【已激活】' : ''}`
          return item
        })
        this.$store.commit('SET_PROCESS_DATA', cloneDeep(this.curVerssionData))
      })
    },

    /**
   * 版本切换
   */
    handleCurVersionChange () {
      const { id } = this.curVerssionData
      const url = window.location.href.replace(/id=\d*/, `id=${id}`)
      this.processLoading = true
      window.location.replace(url)
      window.location.reload()
    },

    async handleCommandSave (command) {
      const flag = this.validataDataForSave()
      if (!flag) return
      await this.handleSave(false)
      if (command === 'activate') {
        this.handleActivate()
      } else if (command === 'publish') {
        this.handlePublish()
      }
    },

    validataDataForSave() {
      const data = this.$refs.g6process.graph.save()
      let flag = true
      // 没有默认节点
      const defaultFlag = data.nodes.some(item => {
        return item.isDefault === true
      })
      if (!defaultFlag) {
        flag = false
        this.$notify({
          type: 'error',
          title: '错误',
          message: '请为状态机设置默认状态'
        })
        return
      }
      for (const node of data.nodes) {
        const { id, code } = node
        const label = node._label || node.label
        // 没有数据
        if (!label || !code) {
          flag = false
          this.$refs.g6process.handleNodeClick(node)
          return
        }
        // code 唯一
        const uniqueCodeFlag = data.nodes.some(item => {
          return item.code === code && item.id !== id
        })
        if (uniqueCodeFlag) {
          flag = false
          this.$refs.g6process.handleNodeClick(node)
          return
        }
        // label 唯一
        const uniqueLabelFlag = data.nodes.some(item => {
          return item._label === label && item.id !== id
        })
        if (uniqueLabelFlag) {
          flag = false
          this.$refs.g6process.handleNodeClick(node)
          return
        }
        // code命名不符合规范
        if (!COMMON_CODE_28I_REG.pattern.test(code)) {
          flag = false
          this.$refs.g6process.handleNodeClick(node)
          return
        }
        // code 长度限制
        if (code.trim.length > 28) {
          flag = false
          this.$refs.g6process.handleNodeClick(node)
          return
        }

        // 没有事件
        const edgeFlag = data.edges.some(edge => {
          return edge.target === id || edge.source === id
        })
        if (!edgeFlag) {
          flag = false
          this.$refs.g6process.handleNodeClick(node)
          this.$notify({
            type: 'error',
            title: '错误',
            message: '请为状态配置事件'
          })
          return
        }
      }
      for (const edge of data.edges) {
        const { label, code } = edge
        if (!label || !code) {
          flag = false
          this.$refs.g6process.handleEdgeClick(edge)
          return
        }
        // code命名不符合规范
        if (!COMMON_CODE_28I_REG.pattern.test(code)) {
          flag = false
          this.$refs.g6process.handleEdgeClick(edge)
          return
        }
      }
      return flag
    },

    // 保存
    async handleSave (showMsg = true) {
      const data = this.$refs.g6process.graph.save()
      const flag = this.validataDataForSave()
      await this.$nextTick()

      if (flag) {
        const edges = data.edges.map(item => {
          const { source, sourceAnchor, target, targetAnchor, label, code, scriptId } = item
          return {
            source,
            sourceAnchor,
            target,
            targetAnchor,
            label,
            code,
            scriptId
          }
        })
        const nodes = data.nodes.map(item => {
          const { id, x, y, _originId, label, _label, _timeStamp, code, isDefault } = item
          return {
            id,
            label: _label || label,
            code,
            isDefault,
            x,
            y,
            type: 'rect-node',
            _originId,
            _timeStamp
          }
        })
        const newData = JSON.stringify({
          edges,
          nodes
        })
        store.save()
        return putHmstatemodelDeploy({
          id: this.modelData.id,
          json: newData
        }).then(res => {
          showMsg && this.$message.success('保存成功')
        }).finally(() => {
          this.processLoading = false
        })
      } else {
        this.processLoading = false
        return Promise.reject(new Error('node valid error'))
      }
    },

    async handleActivate () {
      this.processLoading = true
      putHmstatemodelActivate({
        id: this.modelData.id
      }).then(res => {
        this.$message.success('操作成功')
        this.loadVersionList(this.modelData.key)
      }).finally(() => {
        this.processLoading = false
      })
    },

    async handlePublish () {
      this.processLoading = true
      putHmstatemodelPublish({
        id: this.modelData.id
      }).then(res => {
        this.$message.success('操作成功')
        this.loadVersionList(this.modelData.key)
        // 发布成功以后 手动触发当前选中节点的点击 以 更新 面板动作及属性
        this.initProcess()
      }).finally(() => {
        this.processLoading = false
      })
    },
    handleClose() {
      window.close();
    },
  }
}
</script>

<style scoped>
.process-design-wrap{
  height: 100%;
}
.page-header{
  height: 60px !important;
  position: relative;
  padding: 0;
}
.process-header{
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  box-sizing: border-box;
  padding: 0 28px;
}

.process-header_title{
  font-size: 18px;
}

</style>
